home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: Alpha / Whiteline Alpha.iso / linux / atari / source / source.lzh / atari-linux-0.01pl3 / drivers / block / ramdisk.c < prev   
Encoding:
C/C++ Source or Header  |  1994-06-10  |  5.9 KB  |  231 lines

  1. /*
  2.  *  linux/kernel/blk_drv/ramdisk.c
  3.  *
  4.  *  Written by Theodore Ts'o, 12/2/91
  5.  *
  6.  * This file is subject to the terms and conditions of the GNU General Public
  7.  * License.  See the file README.legal in the main directory of this archive
  8.  * for more details.
  9.  *
  10.  * Modifications by Fred N. van Kempen to allow for bootable root
  11.  * disks (which are used in LINUX/Pro).  Also some cleanups.  03/03/93
  12.  */
  13.  
  14.  
  15. #include <linux/config.h>
  16. #include <linux/sched.h>
  17. #include <linux/minix_fs.h>
  18. #include <linux/fs.h>
  19. #include <linux/kernel.h>
  20. #include <linux/string.h>
  21. #include <asm/system.h>
  22. #include <asm/segment.h>
  23.  
  24. #include <linux/bootinfo.h>
  25.  
  26. #define MAJOR_NR  MEM_MAJOR
  27. #include "blk.h"
  28.  
  29. #define RAMDISK_MINOR    1
  30.  
  31. extern ulong mm_phys_to_virt (ulong addr);
  32.  
  33.  
  34. char    *rd_start;
  35. int    rd_length = 0;
  36. static int rd_blocksizes[2] = {0, 0};
  37.  
  38. static void do_rd_request(void)
  39. {
  40.     int    len;
  41.     char    *addr;
  42.  
  43. repeat:
  44.     INIT_REQUEST;
  45.     addr = rd_start + (CURRENT->sector << 9);
  46.     len = CURRENT->current_nr_sectors << 9;
  47.  
  48.     if ((MINOR(CURRENT->dev) != RAMDISK_MINOR)
  49.         || (addr+len > rd_start+rd_length)) {
  50.         end_request(0);
  51.         goto repeat;
  52.     }
  53.     if (CURRENT-> cmd == WRITE) {
  54.         (void ) memcpy(addr,
  55.                   CURRENT->buffer,
  56.                   len);
  57.     } else if (CURRENT->cmd == READ) {
  58.         (void) memcpy(CURRENT->buffer,
  59.                   addr,
  60.                   len);
  61.     } else
  62.         panic("unknown ramdisk-command");
  63.     end_request(1);
  64.     goto repeat;
  65. }
  66.  
  67. static struct file_operations rd_fops = {
  68.     NULL,            /* lseek - default */
  69.     block_read,        /* read - general block-dev read */
  70.     block_write,        /* write - general block-dev write */
  71.     NULL,            /* readdir - bad */
  72.     NULL,            /* select */
  73.     NULL,            /* ioctl */
  74.     NULL,            /* mmap */
  75.     NULL,            /* no special open code */
  76.     NULL,            /* no special release code */
  77.     block_fsync        /* fsync */
  78. };
  79.  
  80. /*
  81.  * Returns amount of memory which needs to be reserved
  82.  * and copies ramdisk image to the buffer if necessary.
  83.  * It will also set the ROOT DEVICE to the ramdisk.
  84.  */
  85. long rd_init(long mem_start, int length)
  86. {
  87.     int    i;
  88.     char    *cp;
  89.  
  90.     if (register_blkdev(MEM_MAJOR,"rd",&rd_fops)) {
  91.         printk("RAMDISK: Unable to get major %d.\n", MEM_MAJOR);
  92.         return 0;
  93.     }
  94.     blk_dev[MEM_MAJOR].request_fn = DEVICE_REQUEST;
  95.     rd_start = (char *) mem_start;
  96.     rd_length = length;
  97.     cp = rd_start;
  98.     for (i=0; i < length; i++)
  99.         *cp++ = '\0';
  100.  
  101. #ifdef __mc68000__
  102.     if (length > 0) {
  103.         char *rdp;         /* current location of ramdisk */
  104.  
  105.         /* get current address of ramdisk */
  106.         rdp = (char *)mm_phys_to_virt (boot_info.ramdisk_addr);
  107.  
  108.         /* copy the ram disk image */
  109.         memcpy (rd_start, rdp, length);
  110.     }
  111. #endif
  112.  
  113.     for(i=0;i<2;i++) rd_blocksizes[i] = 1024;
  114.     blksize_size[MAJOR_NR] = rd_blocksizes;
  115.  
  116.     return(length);
  117. }
  118.  
  119. /*
  120.  * If the root device is the RAM disk, try to load it.
  121.  * In order to do this, the root device is originally set to the
  122.  * floppy, and we later change it to be RAM disk.
  123.  */
  124. void rd_load(void)
  125. {
  126.     struct buffer_head *bh;
  127.     struct minix_super_block s;
  128.     int        block, tries;
  129.     int        i = 1;
  130.     int        nblocks;
  131.     char        *cp;
  132.  
  133.     /* If no RAM disk specified, give up early. */
  134.     if (!rd_length) return;
  135.     printk("RAMDISK: %d bytes, starting at 0x%x\n",
  136.                     rd_length, (int) rd_start);
  137.  
  138. #ifdef __i386__
  139.     /* If we are doing a diskette boot, we might have to pre-load it. */
  140.     if (MAJOR(ROOT_DEV) != FLOPPY_MAJOR) return;
  141.  
  142.     /*
  143.      * Check for a super block on the diskette.
  144.      * The old-style boot/root diskettes had their RAM image
  145.      * starting at block 512 of the boot diskette.  LINUX/Pro
  146.      * uses the enire diskette as a file system, so in that
  147.      * case, we have to look at block 0.  Be intelligent about
  148.      * this, and check both... - FvK
  149.      */
  150.     for (tries = 0; tries < 1000; tries += 512) {
  151.         block = tries;
  152.         bh = breada(ROOT_DEV,block+1,block,block+2,-1);
  153.         if (!bh) {
  154.             printk("RAMDISK: I/O error while looking for super block!\n");
  155.             return;
  156.         }
  157.  
  158.         /* This is silly- why do we require it to be a MINIX FS? */
  159.         *((struct minix_super_block *) &s) =
  160.             *((struct minix_super_block *) bh->b_data);
  161.         brelse(bh);
  162.         nblocks = s.s_nzones << s.s_log_zone_size;
  163.         if (s.s_magic != MINIX_SUPER_MAGIC &&
  164.             s.s_magic != MINIX_SUPER_MAGIC2) {
  165.             printk("RAMDISK: trying old-style RAM image.\n");
  166.             continue;
  167.         }
  168.  
  169.         if (nblocks > (rd_length >> BLOCK_SIZE_BITS)) {
  170.             printk("RAMDISK: image too big! (%d/%d blocks)\n",
  171.                     nblocks, rd_length >> BLOCK_SIZE_BITS);
  172.             return;
  173.         }
  174.         printk("RAMDISK: Loading %d blocks into RAM disk", nblocks);
  175.  
  176.         /* We found an image file system.  Load it into core! */
  177.         cp = rd_start;
  178.         while (nblocks) {
  179.             if (nblocks > 2) 
  180.                 bh = breada(ROOT_DEV, block, block+1, block+2, -1);
  181.             else
  182.                 bh = bread(ROOT_DEV, block, BLOCK_SIZE);
  183.             if (!bh) {
  184.                 printk("RAMDISK: I/O error on block %d, aborting!\n", 
  185.                 block);
  186.                 return;
  187.             }
  188.             (void) memcpy(cp, bh->b_data, BLOCK_SIZE);
  189.             brelse(bh);
  190.             if (!(nblocks-- & 15)) printk(".");
  191.             cp += BLOCK_SIZE;
  192.             block++;
  193.             i++;
  194.         }
  195.         printk("\ndone\n");
  196.  
  197.         /* We loaded the file system image.  Prepare for mounting it. */
  198.         ROOT_DEV = ((MEM_MAJOR << 8) | RAMDISK_MINOR);
  199.         return;
  200.     }
  201. #else
  202.  
  203. #if 0
  204.     /* Why must the ramdisk contain a Minix filesystem?? This is silly. */
  205.     s = *(struct minix_super_block *)(rd_start + BLOCK_SIZE);
  206.  
  207.     if (s.s_magic != MINIX_SUPER_MAGIC) {
  208.         /* No ram disk image present, assume normal floppy boot */
  209.         printk ("ramdisk has no super block magic number %x\n",
  210.             s.s_magic);
  211.         return;
  212.     }
  213.  
  214.     nblocks = s.s_nzones << s.s_log_zone_size;
  215.     if (nblocks > (rd_length >> BLOCK_SIZE_BITS)) {
  216.         printk("Ram disk image too big!  (%d blocks, %d avail)\n",
  217.                nblocks, rd_length >> BLOCK_SIZE_BITS);
  218.         return;
  219.     }
  220. #else
  221.     nblocks = rd_length >> BLOCK_SIZE_BITS;
  222. #endif
  223.  
  224.     printk("RAMDISK: Loading %d blocks into ram disk", nblocks);
  225.     printk("\ndone\n");
  226.     /* We loaded the file system image.  Prepare for mounting it. */
  227.     ROOT_DEV = ((MEM_MAJOR << 8) | RAMDISK_MINOR);
  228.     return;
  229. #endif
  230. }
  231.